/*
 *  GameManager.cpp
 *
 *  Created by Jason Townes French on 4/30/08.
 *
 */

#include "GameManager.h"
#include "GameState.h"

template<> GameManager* Singleton<GameManager>::ms_Singleton = 0; 

GameManager::GameManager()
{
	//
	mRoot = NULL;
	//mInputManager = NULL;
}

GameManager::~GameManager()
{
	// clean up all the states
	if(mStates)
	{
		while(! mStates->empty())
		{
			mStates->back()->exit();
			mStates->pop_back();
		}
		delete mStates;
	}
	
	/*
	if (mInputManager) 
      delete mInputManager;
	*/
	
	if (mRoot)
	{
		delete mRoot;
	}
}

void GameManager::changeState(GameState* s)
{
	//cleanup the current state
	if(!mStates->empty())
	{
		mStates->back()->exit();
		mStates->pop_back();
	}
	
	//store and init the new state
	mStates->push_back(s);
	mStates->back()->enter(mRoot);
}

RenderWindow* GameManager::getWindow()
{
	return mWindow;
}

GameManager& GameManager::getSingleton()
{
	assert(ms_Singleton);
	return *ms_Singleton;
}

void GameManager::pushState(GameState* s)
{
	// pause current state 
   if (!mStates->empty()) { 
      mStates->back()->pause(); 
   } 

   // store and init the new state 
   mStates->push_back(s); 
   mStates->back()->enter(mRoot);
}

void GameManager::popState()
{
	// cleanup the current state 
	if (!mStates->empty())
	{
		mStates->back()->exit();
		mStates->pop_back();
	}
	
	// resume previous state
	
	if (!mStates->empty())
	{
		mStates->back()->resume();
	}
}

void GameManager::start(GameState* s)
{
	//Boot up Ogre
	mRoot = new Root(); 
	
	//Load the resource paths -> does NOT actually parse/load resources into memory
	setupResources(); 
	
	if (!configure()) return;
	
	//mRoot->addFrameListener(this);
	
	//mInputManager = new InputManager(mRoot->getAutoCreatedWindow());
	//mInputManager->getEventProcessor()->addKeyListener(this);
	// set the initial flag before entering IntroState 
	changeState(s);
	mRoot->startRendering(); 
}

void GameManager::setResourcePath(std::string p)
{
	mResourcePath = p;
}

void GameManager::setupResources()
{
	// Load resource paths from config file
	ConfigFile cf;
	cf.load(mResourcePath + "resources.cfg");
	
	// Go through all sections & settings in the file
	ConfigFile::SectionIterator seci = cf.getSectionIterator();
	String secName, typeName, archName;
	
	while (seci.hasMoreElements())
	{
		secName = seci.peekNextKey();
		ConfigFile::SettingsMultiMap *settings = seci.getNext();
        ConfigFile::SettingsMultiMap::iterator i;
		for (i = settings->begin(); i != settings->end(); ++i)
		{
			typeName = i->first;
            archName = i->second;
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
			// OS X does not set the working directory relative to the app,
			// In order to make things portable on OS X we need to provide
			// the loading with it's own bundle path location
			ResourceGroupManager::getSingleton().addResourceLocation(
                    String(mResourcePath + "/" + archName), typeName, secName);
#else
			ResourceGroupManager::getSingleton().addResourceLocation(
                    archName, typeName, secName);
#endif
		}
	}

}

bool GameManager::configure()
{
	// Show the configuration dialog and initialise the system
	// You can skip this and use root.restoreConfig() to load configuration
	// settings if you were sure there are valid ones saved in ogre.cfg
	if(mRoot->showConfigDialog())
	{
		// If returned true, user clicked OK so initialise
		// Here we choose to let the system create a default rendering window by passing 'true'
		mWindow = mRoot->initialise(true);
		return true;
	}
	else
	{
		return false;
	}
}
